//
// Created by jingyuewu on 25-8-17.
//
#include "boost/asio.hpp"
#include <ctime>
#include <iostream>

int main(int argc, char *argv[]) {
  int port = 17239;
  std::string host = "127.0.0.1";
  try {
    // if (argc != 2) {
    //   std::cerr << "Usage: client <host>" << std::endl;
    //   return 1;
    // }
    boost::asio::io_context io_context;
    boost::asio::ip::tcp::resolver resolver(io_context);

    boost::asio::ip::tcp::resolver::results_type endpoints =
        resolver.resolve(host, std::to_string(port));
    std::cout << "connecting to " << host << ":" << std::to_string(port)
              << std::endl;

    // boost::asio::ip::tcp::socket sock(io_context);
    int socket_buf_len = 10;
    std::vector<boost::asio::ip::tcp::socket> socket_vec;
    socket_vec.reserve(socket_buf_len);

    auto start_reading = [](boost::asio::ip::tcp::socket &socket) {
      std::shared_ptr<std::array<char, 128>> buf_ptr = std::make_shared<std::array<char, 128>>();
      std::shared_ptr<std::function<void(boost::system::error_code, size_t)>>
          read_handler_ptr = std::make_shared<std::function<void(boost::system::error_code, size_t)>>();
      
      *read_handler_ptr = [read_handler_ptr, buf_ptr, &socket](boost::system::error_code ec, size_t len) mutable {
        if (!ec) {
          // 安全地获取端点信息
          boost::system::error_code endpoint_ec;
          auto local_ep = socket.local_endpoint(endpoint_ec);
          if (!endpoint_ec) {
            std::cout << "Socket " << local_ep << " received: ";
          } else {
            std::cout << "Socket received: ";
          }
          
          std::cout.write(buf_ptr->data(), len);
          std::cout.flush();
          
          // 继续下一次异步读取
          socket.async_read_some(boost::asio::buffer(*buf_ptr), *read_handler_ptr);
        } else {
          std::cerr << "Socket error: " << ec.message() << std::endl;
        }
      };
      
      // 启动第一次读取
      socket.async_read_some(boost::asio::buffer(*buf_ptr), *read_handler_ptr);
    };

    // 创建并连接所有socket
    for (int i = 0; i < socket_buf_len; ++i) {
      socket_vec.emplace_back(io_context);
      boost::asio::connect(socket_vec[i], endpoints);
      std::cout << "connected socket " << i << " " << socket_vec[i].local_endpoint() << std::endl;
      
      // 为每个socket启动持续读取
      start_reading(socket_vec[i]);
    }

    io_context.run();
  } catch (std::exception &e) {
    std::cerr << e.what() << std::endl;
  }
  return 0;
}